package gui.cen.tree;

import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import core.tree.Vertex;
import javax.swing.*;
import java.awt.*;
import java.lang.Math.*;
import java.awt.Font.*;
import java.awt.Graphics2D.*;
import gui.utils.Borders;
import gui.utils.Para;
import java.io.FileOutputStream;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class TreePane extends JPanel{
    private TreeDisp td;
    public TreePane(TreeDisp td) {
        super();
        this.td = td;
        this.setBackground(new Color(102, 102, 102));
        this.repaint(); 
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (Para.TREE != null) {
            this.setPreferredSize(new Dimension((int)(Para.TREE.mag/4), (int)(Para.TREE.mag/4)));
            this.revalidate();
            this.setLayout(new FlowLayout(){public Dimension preferredLayoutSize(Container cont) {return (new Dimension((int)Para.TREE.mag, (int)Para.TREE.mag));}});
            Para.TREE.setVertexCoordinatesCircular((int)(td.getWidth()/2), (int)(td.getHeight()/2));
            Graphics2D g2 = (Graphics2D)g;
            displayTree(g2);
        }
        else{
            displayNullTree((Graphics2D)g);
        }
    }

    public void updateTree(){this.repaint();}

    private void displayNullTree(Graphics2D g){
        g.setColor(new Color(178, 178, 178));
        g.drawString("No Tree To View (less than 5 tips available)", (int)(this.getWidth()/2) - 50, 50);
        this.repaint(); 
    }

    private void displayTree(Graphics2D g) {
        g.setFont(Borders.getFont(Borders.GUIFONT));
        Vertex root = Para.TREE.getRoot();
        drawEdges(root, g);
        displayNodes(root, g);
        displayScaleBar(g);
    }
    
    private double scale = 0.01;

    public void setScale(double s){scale = s;}

    private void displayScaleBar(Graphics2D g) {
        g.setColor(new Color(178, 178, 178));
        int startXPos = (Para.TREE.getRoot().getX());
        int scaleSize = 0;
        scaleSize = (int) Math.floor(startXPos + (scale * Para.TREE.mag));
        g.drawLine(startXPos, 16, scaleSize, 16);
        g.drawString(scale + "", ((startXPos - 10) + scaleSize) / 2, 32);

        int xLocation = (Para.TREE.getRoot().getX());
        int startLoc = xLocation;
        for(int c=0; c<Para.TREE.colors.size(); c++){
            g.setColor(Para.TREE.colors.get(c));
            g.fill(new java.awt.Rectangle(xLocation, 40,  1, 5));
            xLocation = xLocation+1;
        }
        g.setColor(new Color(178, 178, 178));
        g.drawString(Para.TREE.getMaxFreq()+"", (xLocation - 5), 58);
        g.drawString("frequency", ((startLoc + (int)((xLocation - startLoc) / 2)) - 20), 58);
        g.drawString("1", startLoc, 58);
        g.drawString("(Genome Location from " + Para.TREE.getStart() + " to " + Para.TREE.getEnd()+")", startLoc, 72);
    }

    private void drawEdges(Vertex v, Graphics2D g){
        g.setColor(new Color(178, 178, 178));
        g.setStroke(new BasicStroke(0.50f));
        Object[] children = v.getChildren().toArray();
        for (int i = 0; i != children.length; i++) {
            Vertex child = (Vertex) children[i];
            g.drawLine(child.getX(), child.getY(), child.getPtrToParent().getX(), child.getPtrToParent().getY());
            if(child.getNoOfChildren() > 0){drawEdges(child, g);}
        }
    }

    private void displayNodes(Vertex v, Graphics2D g) {
        Object[] children = v.getChildren().toArray();
        for (int i = 0; i != children.length; i++) {
            Vertex child = (Vertex) children[i];
            if (Para.DISPLAY_LEAF_TITLES) {
                if(child.getNoOfChildren()==0){
                    boolean backwards = false;
                    int checkX = child.getX() +(int)(Math.cos(child.getChildAngle()) * (100));
                    if(checkX<child.getX()){backwards = true;}
                    if(backwards){g.drawString(child.getTitle(), child.getX()-(child.getTitle().length()*6), child.getY());}
                    else{g.drawString(child.getTitle(), child.getX(), child.getY());}
                }
            }
            if (Para.DISPLAY_LEAF_NODES) {
                if (child.getNoOfChildren() == 0) {
                    g.setColor(child.getColIn());
                    g.fillOval(child.getX(), child.getY()-(int)(child.getDiameter()/2), child.getDiameter(), child.getDiameter());
                    g.setStroke(new BasicStroke(1.00f));
                    g.setColor(child.getColOut());
                    g.drawOval(child.getX(), child.getY()-(int)(child.getDiameter()/2), child.getDiameter(), child.getDiameter());
                    g.setStroke(new BasicStroke(1.00f));
                }
            }
            if (child.getNoOfChildren() == 0) {
                if (child.getHighlight()) {
                    g.setColor(Color.red);
                    g.drawOval(child.getX(), child.getY()-(int)((child.getDiameter()+4)/2), child.getDiameter()+4, child.getDiameter()+4);
                    g.setColor(child.getColIn());
                }
            }

            if(child.getNoOfChildren() > 0){displayNodes(child, g);}
        }
    }
    
    public void makePDF(String filename){
        Document document = new Document(new com.lowagie.text.Rectangle(this.getWidth(), this.getHeight()));
        try{
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            Graphics2D g2 = cb.createGraphics(this.getWidth(), this.getHeight());           
            if(Para.TREE!=null){
                Para.TREE.setVertexCoordinatesCircular(Para.TREE.getRoot().getX(), Para.TREE.getRoot().getY());
                displayTree(g2);
            }
            g2.dispose();
        }
        catch(Exception e){}
        document.close();
    } 
}